﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Models;
using Tecnosop.WebUI.Infrastructure.Notification;
using Telerik.Web.Mvc;
using System.Web.UI;
using System.Data.Entity.Validation;
using System.Data;


namespace Tecnosop.WebUI.Controllers
{
    [Authorize]
    public partial class ConvenioController : Controller
    {
        private Entidades db = new Entidades();

        #region CRUD

        public virtual ActionResult Index(bool soloVigentes = true)
        {
            ViewBag.Vigentes = soloVigentes;

            this.ShowMessage(MessageType.Warning, "Se están mostrando " + (soloVigentes ? "sólo los convenios vigentes." : "todos los convenios; vigentes y terminados."));
            return View((soloVigentes ? db.CONVENIO.Where(c => c.CONVENIO_VIGENTE ?? false) : db.CONVENIO).ToList());
        }

        public virtual ActionResult Details(int id)
        {
            CONVENIO convenio = db.CONVENIO.Find(id);
            var equiposEnConvenio = db.EQUIPO_EN_CONVENIO.Where(e => e.NUMERO_CONVENIO == convenio.NUMERO_CONVENIO && e.VISIBLE.Value);

            List<EquipoEnConvenio> equipos = new List<EquipoEnConvenio>();
            foreach (var equipo in equiposEnConvenio)
            {
                equipos.Add(new EquipoEnConvenio
                    {
                        NUMERO_CONVENIO = equipo.NUMERO_CONVENIO,
                        NUMERO_EQUIPO_EN_CONVENIO = equipo.NUMERO_EQUIPO_EN_CONVENIO,
                        NUMERO_CONSIGNACION = equipo.CONSIGNACION_EQUIPO.CONSIGNACION,
                        NUMERO_CONSIGNACION_ORIGINAL = equipo.CONSIGNACION_EQUIPO.CONSIGNACION,
                        TIPO_EQUIPO = equipo.CONSIGNACION_EQUIPO.EQUIPO.TIPO_EQUIPO,
                        MARCA_EQUIPO = equipo.CONSIGNACION_EQUIPO.EQUIPO.ITEM.MARCA,
                        MODELO_EQUIPO = equipo.CONSIGNACION_EQUIPO.EQUIPO.ITEM.MODELO,
                        CONTADOR_SALIDA_BODEGA_EQUIPO_BN = equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_BN ?? 0,
                        CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR = equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR ?? 0,
                        FECHA_INSTALACION = equipo.FECHA_INSTALACION ?? DateTime.MinValue,
                        DIRECCION_EQUIPO = equipo.DIRECCION_EQUIPO,
                        NOMBRE_ENCARGADO_EQUIPO = equipo.NOMBRE_ENCARGADO_EQUIPO,
                        TELEFONO_ENCARGADO_EQUIPO = equipo.TELEFONO_ENCARGADO_EQUIPO,
                    });
            }

            return View(new DetallesConvenioViewModel
                {
                    NUMERO_CONVENIO = convenio.NUMERO_CONVENIO,
                    RUT_CLIENTE = convenio.RUT_CLIENTE,
                    NOMBRE_CLIENTE = convenio.CLIENTE.NOMBRE,
                    FECHA_CONVENIO = convenio.FECHA_CONVENIO ?? DateTime.MinValue,
                    FECHA_VENCIMIENTO = convenio.FECHA_VENCIMIENTO ?? DateTime.MinValue,
                    DIA_FACTURACION = convenio.DIA_FACTURACION ?? 0,
                    RUT_REPRESENTANTE_LEGAL = convenio.RUT_REPRESENTANTE_LEGAL,
                    NOMBRE_REPRESENTANTE_LEGAL = convenio.NOMBRE_REPRESENTANTE_LEGAL,
                    TELEFONO_REPRESENTANTE_LEGAL = convenio.TELEFONO_REPRESENTANTE_LEGAL,
                    EquiposEnConvenio = equipos//db.EQUIPO_EN_CONVENIO.Where(e => e.NUMERO_CONVENIO == convenio.NUMERO_CONVENIO)
                });
        }

        public virtual ActionResult Create()
        {
            ViewBag.RutsClientes = db.CLIENTE.Select(c => c.RUT_CLIENTE).ToList();

            return View(new ConvenioViewModel
                {
                    FECHA_CONVENIO = DateTime.Today.Date
                });
        } 

        [HttpPost]
        public virtual ActionResult Create(ConvenioViewModel convenioVM)
        {
            ViewBag.RutsClientes = db.CLIENTE.Select(c => c.RUT_CLIENTE).ToList();

            if (ModelState.IsValid)
            {
                try
                {
                    CONVENIO C = new CONVENIO
                    {
                        RUT_CLIENTE = convenioVM.RUT_CLIENTE,
                        DIA_FACTURACION = convenioVM.DIA_FACTURACION,
                        FECHA_CONVENIO = convenioVM.FECHA_CONVENIO,
                        FECHA_VENCIMIENTO = convenioVM.FECHA_VENCIMIENTO,
                        CONVENIO_VIGENTE = true,
                        PERIODO_DE_FACTURACION = convenioVM.PERIODO_DE_FACTURACION,
                        RUT_REPRESENTANTE_LEGAL = convenioVM.RUT_REPRESENTANTE_LEGAL,
                        NOMBRE_REPRESENTANTE_LEGAL = convenioVM.NOMBRE_REPRESENTANTE_LEGAL,
                        TELEFONO_REPRESENTANTE_LEGAL = convenioVM.TELEFONO_REPRESENTANTE_LEGAL
                    };
                    db.CONVENIO.Add(C);
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "El convenio [" + C.NUMERO_CONVENIO + "] fue iniciado exitosamente.");
                    return RedirectToAction(Actions.Details(C.NUMERO_CONVENIO));
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un error al intentar iniciar el convenio.");
                    return View(convenioVM);
                }
            }

            this.ShowMessage(MessageType.Warning, "Datos incorrectos, dañados o error durante su transmisión.");
            return View(convenioVM);
        }

        public virtual ActionResult Edit(int id)
        {
            CONVENIO convenio = db.CONVENIO.Find(id);
            return View(new EditConvenioViewModel
                {
                    NUMERO_CONVENIO = convenio.NUMERO_CONVENIO,
                    RUT_CLIENTE = convenio.RUT_CLIENTE,
                    NOMBRE_CLIENTE = convenio.CLIENTE.NOMBRE,
                    FECHA_CONVENIO = convenio.FECHA_CONVENIO ?? DateTime.MinValue,
                    FECHA_VENCIMIENTO = convenio.FECHA_VENCIMIENTO,
                    DIA_FACTURACION = convenio.DIA_FACTURACION ?? -1,
                    RUT_REPRESENTANTE_LEGAL = convenio.RUT_REPRESENTANTE_LEGAL,
                    NOMBRE_REPRESENTANTE_LEGAL = convenio.NOMBRE_REPRESENTANTE_LEGAL,
                    TELEFONO_REPRESENTANTE_LEGAL = convenio.TELEFONO_REPRESENTANTE_LEGAL
                });
        }

        [HttpPost]
        public virtual ActionResult Edit(int id, EditConvenioViewModel convenioVM)
        {
            try
            {
                CONVENIO convenio = db.CONVENIO.Single(c => c.NUMERO_CONVENIO == id);

                convenio.DIA_FACTURACION = convenioVM.DIA_FACTURACION;
                convenio.FECHA_VENCIMIENTO = convenioVM.FECHA_VENCIMIENTO;
                convenio.NOMBRE_REPRESENTANTE_LEGAL = convenioVM.NOMBRE_REPRESENTANTE_LEGAL;
                convenio.RUT_REPRESENTANTE_LEGAL = convenioVM.RUT_REPRESENTANTE_LEGAL;
                convenio.TELEFONO_REPRESENTANTE_LEGAL = convenioVM.TELEFONO_REPRESENTANTE_LEGAL;

                db.Entry(convenio).State = EntityState.Modified;
                db.SaveChanges();

                this.ShowMessage(MessageType.Success, "Cambios guardados correctamente.");
                return RedirectToAction(Actions.Details(id));
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "Ocurrió un error al intentar guardar los cambios");
                return View(convenioVM);
            }
        }

        public virtual ActionResult Delete(int id)
        {
            CONVENIO convenio = db.CONVENIO.Find(id);

            this.ShowMessage(MessageType.Warning, "Está a punto de finalizar el convenio número: " + id, false);

            return View(new DetallesConvenioViewModel
            {
                NUMERO_CONVENIO = convenio.NUMERO_CONVENIO,
                RUT_CLIENTE = convenio.RUT_CLIENTE,
                NOMBRE_CLIENTE = convenio.CLIENTE.NOMBRE,
                FECHA_CONVENIO = convenio.FECHA_CONVENIO ?? DateTime.MinValue,
                FECHA_VENCIMIENTO = convenio.FECHA_VENCIMIENTO ?? DateTime.MinValue,
                DIA_FACTURACION = convenio.DIA_FACTURACION ?? 0,
                RUT_REPRESENTANTE_LEGAL = convenio.RUT_REPRESENTANTE_LEGAL,
                NOMBRE_REPRESENTANTE_LEGAL = convenio.NOMBRE_REPRESENTANTE_LEGAL,
                TELEFONO_REPRESENTANTE_LEGAL = convenio.TELEFONO_REPRESENTANTE_LEGAL,
                EquiposEnConvenio = new List<EquipoEnConvenio>()//db.EQUIPO_EN_CONVENIO.Where(e => e.NUMERO_CONVENIO == convenio.NUMERO_CONVENIO)
            });
        }

        [HttpPost, ActionName("Delete")]
        public virtual ActionResult DeleteConfirmed(int id)
        {
            try
            {
                CONVENIO convenio = db.CONVENIO.Find(id);
                convenio.CONVENIO_VIGENTE = false;

                foreach (var equipo in convenio.EQUIPO_EN_CONVENIO)
                {
                    equipo.VISIBLE = false;
                }

                db.Entry(convenio).State = EntityState.Modified;
                db.SaveChanges(); 

                this.ShowMessage(MessageType.Success, "El convenio fue terminado correctamente.");
                return RedirectToAction(Actions.Index());
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "Ocurrio un error al intentar terminar el convenio.");
                return RedirectToAction(Actions.Delete(id));
            }
        }

        #endregion

        #region Equipos en convenio

        [HttpPost]
        public virtual ActionResult GridAddEquipoEnConvenio(int id)
        {
            GridCreateEquipoEnConvenio equipoVM = new GridCreateEquipoEnConvenio();

            if (TryUpdateModel(equipoVM))
            {
                EQUIPO_EN_CONVENIO equipo = new EQUIPO_EN_CONVENIO
                    {
                        //CONVENIO = db.CONVENIO.Find(id),
                        NUMERO_CONVENIO = id,
                        //CONSIGNACION_EQUIPO = db.CONSIGNACION_EQUIPO.SingleOrDefault(c => c.CONSIGNACION == equipoVM.NUMERO_CONVENIO),
                        //NUMERO_SERIE = db.CONSIGNACION_EQUIPO.Find(equipoVM.NUMERO_CONSIGNACION).NUMERO_SERIE,
                        NUMERO_SERIE = db.CONSIGNACION_EQUIPO.SingleOrDefault(c => c.CONSIGNACION == equipoVM.NUMERO_CONSIGNACION).NUMERO_SERIE,
                        CONTADOR_SALIDA_BODEGA_EQUIPO_BN = equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_BN,
                        CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR = equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR,
                        DIRECCION_EQUIPO = equipoVM.DIRECCION_EQUIPO,
                        FECHA_INSTALACION = equipoVM.FECHA_INSTALACION ?? DateTime.Today,
                        NOMBRE_ENCARGADO_EQUIPO = equipoVM.NOMBRE_ENCARGADO_EQUIPO,
                        TELEFONO_ENCARGADO_EQUIPO = equipoVM.TELEFONO_ENCARGADO_EQUIPO,
                        VISIBLE = true
                    };
                db.EQUIPO_EN_CONVENIO.Add(equipo);

                db.SaveChanges();
            }

            return RedirectToAction(Actions.Details(id));
        }

        [HttpPost]
        public virtual ActionResult GridDeleteEquipoEnConvenio(int NUMERO_EQUIPO_EN_CONVENIO, int NUMERO_CONVENIO)
        {
            EQUIPO_EN_CONVENIO equipo = db.EQUIPO_EN_CONVENIO.Find(NUMERO_CONVENIO, NUMERO_EQUIPO_EN_CONVENIO);
            equipo.VISIBLE = false;
            //db.EQUIPO_EN_CONVENIO.Remove(equipo);
            db.Entry(equipo).State = EntityState.Modified;
            db.SaveChanges();

            return RedirectToAction(Actions.Details(NUMERO_CONVENIO));
        }

        [HttpPost]
        public virtual ActionResult GridEditEquipoEnConvenio()
        {
            EQUIPO_EN_CONVENIO equipoVM = new EQUIPO_EN_CONVENIO();

            if (TryUpdateModel(equipoVM))
            {
                EQUIPO_EN_CONVENIO equipo = db.EQUIPO_EN_CONVENIO.Find(equipoVM.NUMERO_CONVENIO, equipoVM.NUMERO_EQUIPO_EN_CONVENIO);

                equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_BN = equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_BN;
                equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR = equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR;
                equipo.FECHA_INSTALACION = equipoVM.FECHA_INSTALACION;
                equipo.DIRECCION_EQUIPO = equipoVM.DIRECCION_EQUIPO;
                equipo.NOMBRE_ENCARGADO_EQUIPO = equipoVM.NOMBRE_ENCARGADO_EQUIPO;
                equipo.TELEFONO_ENCARGADO_EQUIPO = equipoVM.TELEFONO_ENCARGADO_EQUIPO;

                db.Entry(equipo).State = EntityState.Modified;
                db.SaveChanges();
            }

            return RedirectToAction(Actions.Details(equipoVM.NUMERO_CONVENIO));
        }

        public virtual ActionResult DetailsEquipoEnConvenio(int id, int NUMERO_EQUIPO_EN_CONVENIO)
        {
            return View(db.EQUIPO_EN_CONVENIO.Find(id, NUMERO_EQUIPO_EN_CONVENIO));
        }

        public virtual ActionResult ConveniosSinFacturar( /*DateTime fecha*/)
        {

            //db.CONVENIO.Where();
            //db.FACTURA.Where(f => f.FECHA_INSTALACION);

            DateTime HoyDia = DateTime.Today;

            //IEnumerable<CONVENIO> conv = db.CONVENIO.Where(q => q.FECHA_CONVENIO.Value.Day == fecha.Value.Day);
            //foreach(var c in conv)
            //{
            //var asd = db.CONVENIO.

            //List<CONVENIO> convenios = new List<CONVENIO>();
            //var mediciones = db.MEDICIONES.Where(t => !t.MEDICION_FACTURADA);
            //foreach (var medicion in mediciones)
            //{
            //    convenios.Add(db.CONVENIO.Find(medicion.NUMERO_CONVENIO));
            //}


            //convenios.Dis
            //}
            DateTime fecha = DateTime.Today;
            int d1=fecha.AddDays(1.0).Day;
            int d2=fecha.AddDays(2.0).Day;;
            int d3=fecha.AddDays(3.0).Day;;
            int d4=fecha.AddDays(4.0).Day;;
            int d5=fecha.AddDays(5.0).Day;;
            int ld1=fecha.AddDays(-1.0).Day;;
            int ld2=fecha.AddDays(-2.0).Day;;
            int ld3=fecha.AddDays(-3.0).Day;;
            int ld4=fecha.AddDays(-4.0).Day;;
            int ld5=fecha.AddDays(-5.0).Day; ;
            System.Data.Linq.SqlClient.SqlMethods.DateDiffMonth(fecha, fecha);
            
            var convenios = db.CONVENIO.Where(y => 
             y.DIA_FACTURACION.Value == fecha.Day
           || y.DIA_FACTURACION.Value == d1
           || y.DIA_FACTURACION.Value == d2
           || y.DIA_FACTURACION.Value == d3
           || y.DIA_FACTURACION.Value == d4
           || y.DIA_FACTURACION.Value == d5
           || y.DIA_FACTURACION.Value == ld1
           || y.DIA_FACTURACION.Value == ld2
           || y.DIA_FACTURACION.Value == ld3
           || y.DIA_FACTURACION.Value == ld4
           || y.DIA_FACTURACION.Value == ld5
           //|| System.Data.Linq.SqlClient.SqlMethods.DateDiffMonth(fecha, fecha) > y.PERIODO_DE_FACTURACION
           );

            var mediciones = db.MEDICIONES.Where(y => !y.MEDICION_FACTURADA);
            
            var convenios2= (from m in mediciones
                            //from c in db.CONVENIO
                            join c in db.CONVENIO on m.NUMERO_CONVENIO equals c.NUMERO_CONVENIO
                            select new {c.NUMERO_CONVENIO}).Distinct();
            
            List<CONVENIO> conveniosMedicion = new List<CONVENIO>();

            foreach (var item in convenios2)
            {
                conveniosMedicion.Add(db.CONVENIO.Find(item.NUMERO_CONVENIO));
            }
           

                            

            List <ConvenioSinFacturarViewModel> conv = new List<ConvenioSinFacturarViewModel> ();
            foreach (var c in convenios)
            {
              

                var med = db.MEDICIONES.Where(m => m.NUMERO_CONVENIO == c.NUMERO_CONVENIO && m.MEDICION_FACTURADA == false);
                ConvenioSinFacturarViewModel aux = new ConvenioSinFacturarViewModel
                {
                    Dia_facturacion = c.DIA_FACTURACION.Value,
                    Numero_convenio = c.NUMERO_CONVENIO,
                    Rut = c.RUT_CLIENTE,
                    mediciones=med.ToList()
                };

                conv.Add(aux);
            }

            
            return View(conv);
        }

        public virtual ActionResult EditEquipoEnConvenio(int id, int NUMERO_EQUIPO_EN_CONVENIO)
        {
            EQUIPO_EN_CONVENIO equipo = db.EQUIPO_EN_CONVENIO.Find(id, NUMERO_EQUIPO_EN_CONVENIO);
            return View(new EditEquipoEnConvenio
                {
                    NUMERO_EQUIPO_EN_CONVENIO = equipo.NUMERO_EQUIPO_EN_CONVENIO,
                    NUMERO_SERIE = equipo.NUMERO_SERIE,
                    NUMERO_CONVENIO = equipo.NUMERO_CONVENIO,
                    FECHA_INSTALACION = equipo.FECHA_INSTALACION,
                    DIRECCION_EQUIPO = equipo.DIRECCION_EQUIPO,
                    CONTADOR_SALIDA_BODEGA_EQUIPO_BN = equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_BN == 0 ? null : equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_BN,
                    CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR = equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR == 0 ? null : equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR,
                    NOMBRE_ENCARGADO_EQUIPO = equipo.NOMBRE_ENCARGADO_EQUIPO,
                    TELEFONO_ENCARGADO_EQUIPO = equipo.TELEFONO_ENCARGADO_EQUIPO
                });
        }

        [HttpPost]
        public virtual ActionResult EditEquipoEnConvenio(EditEquipoEnConvenio equipoVM)
        {
            try
            {
                bool error = false;

                EQUIPO_EN_CONVENIO equipo = db.EQUIPO_EN_CONVENIO.Find(equipoVM.NUMERO_CONVENIO, equipoVM.NUMERO_EQUIPO_EN_CONVENIO);

                #region Comprobar que no hayan mediciones
                if (equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_BN.HasValue)
                {
                    error = !ActualizarContador(ref equipo, EnBN: true, nuevo_contador: equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_BN.Value);
                }
                
                if (equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR.HasValue)
                {
                    error = !ActualizarContador(ref equipo, EnBN: false, nuevo_contador: equipoVM.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR.Value);
                }
                #endregion

                equipo.FECHA_INSTALACION = equipoVM.FECHA_INSTALACION;
                equipo.DIRECCION_EQUIPO = equipoVM.DIRECCION_EQUIPO;
                equipo.NOMBRE_ENCARGADO_EQUIPO = equipoVM.NOMBRE_ENCARGADO_EQUIPO;
                equipo.TELEFONO_ENCARGADO_EQUIPO = equipoVM.TELEFONO_ENCARGADO_EQUIPO;

                db.Entry(equipo).State = EntityState.Modified;
                db.SaveChanges();

                if (!error)
                {
                    this.ShowMessage(MessageType.Success, "Se guardaron correctamente los cambios.");
                }
                else
                {
                    return RedirectToAction(Actions.EditEquipoEnConvenio(equipoVM.NUMERO_CONVENIO, equipoVM.NUMERO_EQUIPO_EN_CONVENIO));
                }
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "No se guardaron los cambios debido a un error.");
            }

            return RedirectToAction(Actions.DetailsEquipoEnConvenio(equipoVM.NUMERO_CONVENIO, equipoVM.NUMERO_EQUIPO_EN_CONVENIO));
        }

        private bool ActualizarContador(ref EQUIPO_EN_CONVENIO equipo, bool EnBN, int nuevo_contador)
        {
            if (!equipo.MEDICIONES.Where(m => EnBN ? m.MEDICION__BN : !m.MEDICION__BN).Any()) //no hay mediciones
            {
                if (EnBN)
                {
                    equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_BN = nuevo_contador;
                }
                else
                {
                    equipo.CONTADOR_SALIDA_BODEGA_EQUIPO_COLOR = nuevo_contador;
                }

                db.Entry(equipo).State = EntityState.Modified;
                db.SaveChanges();

                return true;
            }
            else
            {
                this.ShowMessage(MessageType.Error, "No se puede editar el contador " + (EnBN ? "blanco y negro" : "color") + " ya que existen mediciones. Intente eliminar las mediciones primero");
                return false;
            }
        }

        [HttpPost]
        public virtual ActionResult EditFormasDePago(FormasDePagoViewModel formasDePagoVM)
        {
            try
            {
                EQUIPO_EN_CONVENIO equipo = db.EQUIPO_EN_CONVENIO.Find(formasDePagoVM.NUMERO_CONVENIO, formasDePagoVM.NUMERO_EQUIPO_EN_CONVENIO);

                if (formasDePagoVM.HayCargoFijo)
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.PAGO_TIPO_CARGO_FIJO != null))
                    {
                        FORMA__DE_PAGO formaDePagoCargoFijo = equipo.FORMA__DE_PAGO.First(e => e.PAGO_TIPO_CARGO_FIJO != null);
                        formaDePagoCargoFijo.UF = formasDePagoVM.UFCargoFijo;
                        db.Entry(formaDePagoCargoFijo).State = EntityState.Modified;

                        //db.SaveChanges();

                        PAGO_TIPO_CARGO_FIJO cargoFijo = formaDePagoCargoFijo.PAGO_TIPO_CARGO_FIJO;
                        cargoFijo.PRECIO_CARGO_FIJO = formasDePagoVM.PrecioCargoFijo;
                        db.Entry(cargoFijo).State = EntityState.Modified;

                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA__DE_PAGO cargoFijo = new FORMA__DE_PAGO
                            {
                                UF = formasDePagoVM.UFCargoFijo,
                                ES_CARGO_FIJO = true
                            };
                        cargoFijo.PAGO_TIPO_CARGO_FIJO = new PAGO_TIPO_CARGO_FIJO
                        {
                            PRECIO_CARGO_FIJO = formasDePagoVM.PrecioCargoFijo
                        };
                        equipo.FORMA__DE_PAGO.Add(cargoFijo);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.PAGO_TIPO_CARGO_FIJO != null))
                    {
                        FORMA__DE_PAGO formaDePago = equipo.FORMA__DE_PAGO.First(e => e.PAGO_TIPO_CARGO_FIJO != null);
                        PAGO_TIPO_CARGO_FIJO CargoFijo = formaDePago.PAGO_TIPO_CARGO_FIJO;

                        db.PAGO_TIPO_CARGO_FIJO.Remove(CargoFijo);
                        db.SaveChanges();

                        db.FORMA__DE_PAGO.Remove(formaDePago);
                        db.SaveChanges();
                        //equipo.FORMA__DE_PAGO.Remove(equipo.FORMA__DE_PAGO.First(e => e.PAGO_TIPO_CARGO_FIJO != null));
                    }
                }

                if (formasDePagoVM.HayMinimoGarantizadoBlancoYNegro)
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.MING_B_N != null))
                    {
                        MING_B_N MinBN = equipo.FORMA__DE_PAGO.First(e => e.MING_B_N != null).MING_B_N;
                        MinBN.MING = formasDePagoVM.PrecioMinGBlancoyNegro; //CANTIDAD
                        MinBN.FORMA__DE_PAGO.UF = formasDePagoVM.UFMinBN;

                        if (formasDePagoVM.UFMinBN)
                        {
                            MinBN.FORMA__DE_PAGO.FACTOR_UF = formasDePagoVM.PrecioHojaBlancoynegro;
                        }
                        else
                        {
                            MinBN.PRECIO_HOJA = (int)formasDePagoVM.PrecioHojaBlancoynegro;
                        }

                        db.Entry(MinBN).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA__DE_PAGO MinBN = new FORMA__DE_PAGO
                        {
                            UF = formasDePagoVM.UFMinBN
                        };

                        MinBN.MING_B_N = new MING_B_N
                        {
                            MING = formasDePagoVM.PrecioMinGBlancoyNegro,
                        };

                        if (formasDePagoVM.UFMinBN)
                        {
                            MinBN.FACTOR_UF = formasDePagoVM.PrecioHojaBlancoynegro;
                        }
                        else
                        {
                            MinBN.MING_B_N.PRECIO_HOJA = (int)formasDePagoVM.PrecioHojaBlancoynegro;
                        }

                        equipo.FORMA__DE_PAGO.Add(MinBN);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.MING_B_N != null))
                    {
                        FORMA__DE_PAGO formaDePago = equipo.FORMA__DE_PAGO.First(e => e.MING_B_N != null);
                        MING_B_N MinBN = formaDePago.MING_B_N;

                        db.MING_B_N.Remove(MinBN);
                        db.SaveChanges();

                        db.FORMA__DE_PAGO.Remove(formaDePago);
                        db.SaveChanges();

                        //equipo.FORMA__DE_PAGO.Remove(equipo.FORMA__DE_PAGO.First(e => e.MING_B_N != null));
                        //db.SaveChanges();
                    }
                }

                if (formasDePagoVM.HayMinimoGarantizadoColor)
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.MING_COLOR != null))
                    {
                        MING_COLOR MinGC = equipo.FORMA__DE_PAGO.First(e => e.MING_COLOR != null).MING_COLOR;
                        MinGC.MING = formasDePagoVM.PrecioMinGColor;
                        MinGC.FORMA__DE_PAGO.UF = formasDePagoVM.UFMinColor;

                        if (formasDePagoVM.UFMinColor)
                        {
                            MinGC.FORMA__DE_PAGO.FACTOR_UF = formasDePagoVM.PrecioHojaBlancoynegro;
                        }
                        else
                        {
                            MinGC.PRECIO_HOJA = (int)formasDePagoVM.PrecioHojaBlancoynegro;
                        }

                        db.Entry(MinGC).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA__DE_PAGO MinGC = new FORMA__DE_PAGO
                        {
                            UF = formasDePagoVM.UFMinColor
                        };

                        MinGC.MING_COLOR = new MING_COLOR
                        {
                            MING = formasDePagoVM.PrecioMinGColor,
                        };

                        if (formasDePagoVM.UFMinColor)
                        {
                            MinGC.FACTOR_UF = formasDePagoVM.PrecioHojaColor;
                        }
                        else
                        {
                            MinGC.MING_COLOR.PRECIO_HOJA = (int)formasDePagoVM.PrecioHojaColor;
                        }

                        equipo.FORMA__DE_PAGO.Add(MinGC);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (equipo.FORMA__DE_PAGO.Any(e => e.MING_COLOR != null))
                    {
                        FORMA__DE_PAGO formaDePAgo = equipo.FORMA__DE_PAGO.First(e => e.MING_COLOR != null);
                        MING_COLOR MinG = formaDePAgo.MING_COLOR;

                        db.MING_COLOR.Remove(MinG);
                        db.SaveChanges();

                        db.FORMA__DE_PAGO.Remove(formaDePAgo);
                        db.SaveChanges();
                    }
                }

                this.ShowMessage(MessageType.Success, "Se guardaron los cambios correctamente.");
                return RedirectToAction(Actions.DetailsEquipoEnConvenio(formasDePagoVM.NUMERO_CONVENIO, formasDePagoVM.NUMERO_EQUIPO_EN_CONVENIO));
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "No se pudo guardar los cambios de las formas de pago.");
                return RedirectToAction(Actions.DetailsEquipoEnConvenio(formasDePagoVM.NUMERO_CONVENIO, formasDePagoVM.NUMERO_EQUIPO_EN_CONVENIO));
            }
        }

        #endregion

        #region Validaciones

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult VerificarEquipo(int IdEquipo)
        {
            if (!db.EQUIPO.Any(e => e.CODIGO_ITEM == IdEquipo))
            {
                return Json("El ID ingresado no corresponde a ningún equipo", JsonRequestBehavior.AllowGet);
            }
            //else if (!db.EQUIPO_EN_CONVENIO
            //            //.Where(e => e.ESTA_EN_CONVENIO ?? false)
            //            .Any(e => e.CODIGO_ITEM == IdEquipo))
            //{
                //return Json("El equipo ya está asignado a otro convenio", JsonRequestBehavior.AllowGet);
            //}
            else
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ExisteRut(string RUT_CLIENTE)
        {
            return Json(db.CLIENTE.Any(c => c.RUT_CLIENTE.Equals(RUT_CLIENTE)), JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaBusquedaVacia(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "Numero":
                    int num_convenio;
                    if (Int32.TryParse(AreaBusqueda, out num_convenio))
                    {
                        return db.CONVENIO.Any(c => c.NUMERO_CONVENIO == num_convenio) ?
                               Json(true, JsonRequestBehavior.AllowGet) :
                               Json("No se encontraron convenios con el código ingresado", JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json("El código ingresado no es correcto (no puede contener letras, sólo números)", JsonRequestBehavior.AllowGet);
                    }
                case "Rut":
                    return db.CONVENIO.Any(c => c.RUT_CLIENTE == AreaBusqueda) ?
                        Json(true, JsonRequestBehavior.AllowGet) :
                        Json("No se encontraron clientes de Rut: " + AreaBusqueda + " en convenio", JsonRequestBehavior.AllowGet);
                case "Nombre":
                    return db.CONVENIO.Any(c => c.CLIENTE.NOMBRE.Contains(AreaBusqueda)) ?
                        Json(true, JsonRequestBehavior.AllowGet) :
                        Json("No se encontraron clientes que tengan \"" + AreaBusqueda + "\" en convenio", JsonRequestBehavior.AllowGet);
                default:
                    return Json("Criterio de búsqueda desconocido", JsonRequestBehavior.AllowGet);
            }
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult VerificarConsignacion(int? NUMERO_CONSIGNACION_ORIGINAL, int NUMERO_CONSIGNACION)
        {
            if (NUMERO_CONSIGNACION == 0 && NUMERO_CONSIGNACION_ORIGINAL == 0)
            {
                return Json("No existe ningún equipo con la consignación ingresada", JsonRequestBehavior.AllowGet);
            }
            if (NUMERO_CONSIGNACION == NUMERO_CONSIGNACION_ORIGINAL)
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
            if (db.CONSIGNACION_EQUIPO.Any(c => c.CONSIGNACION == NUMERO_CONSIGNACION))  //Verificar que exista el numero de consignacion
            {
                //Verificar que la consignacion no esté actualmente en otro convenio
                return db.EQUIPO_EN_CONVENIO.Any(e => e.CONSIGNACION_EQUIPO.CONSIGNACION == NUMERO_CONSIGNACION && e.VISIBLE.Value)
                    ? Json("El equipo consignado ya está en otro convenio", JsonRequestBehavior.AllowGet)
                    : Json(true, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json("No existe ningún equipo con la consignación ingresada", JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region Busqueda

        [ChildActionOnly]
        public virtual ActionResult Search()
        {
            return PartialView();
        }

        public virtual ActionResult Busqueda()
        {
            return View();
        }

        public virtual ActionResult ResultadoBusqueda(string Criterios, string AreaBusqueda, bool SoloVigentes)
        {
            ResultadoBusquedaConvenioViewModel r = new ResultadoBusquedaConvenioViewModel();
            r.CriterioParaOrdenar = Criterios;

            switch (Criterios)
            {
                case "Numero":
                    int num_convenio;
                    r.Resultado = Int32.TryParse(AreaBusqueda, out num_convenio)
                        ? SoloVigentes
                            ? db.CONVENIO.Where(c => c.NUMERO_CONVENIO == num_convenio && (c.CONVENIO_VIGENTE ?? false)).ToList()
                            : db.CONVENIO.Where(c => c.NUMERO_CONVENIO == num_convenio).ToList()
                        : new List<CONVENIO>();

                    return View(r);
                case "Rut":
                    r.Resultado = SoloVigentes
                        ? db.CONVENIO.Where(c => c.RUT_CLIENTE == AreaBusqueda && (c.CONVENIO_VIGENTE ?? false)).ToList()
                        : db.CONVENIO.Where(c => c.RUT_CLIENTE == AreaBusqueda).ToList();

                    return View(r);
                case "Nombre":
                    r.Resultado = SoloVigentes
                        ? db.CONVENIO.Where(c => c.CLIENTE.NOMBRE.Contains(AreaBusqueda) && (c.CONVENIO_VIGENTE ?? false)).ToList()
                        : db.CONVENIO.Where(c => c.CLIENTE.NOMBRE.Contains(AreaBusqueda)).ToList();

                    return View(r);
                default:
                    return PartialView(Views.Search);
            }
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
